package cn.jiedanba.itext5.gm.sign.test;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.bouncycastle.jcajce.provider.digest.SM3;
import org.junit.Test;
import org.ofdrw.gm.ses.v4.SESeal;
import org.ofdrw.sign.signContainer.SESV4ContainerV2;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.security.TSAClient;

import cn.jiedanba.itext5.gm.sign.ITextGM;
import cn.jiedanba.itext5.gm.sign.timestamp.GMTSAClient;
import cn.jiedanba.itext5.gm.sign.timestamp.GMTimeStampHook;
import cn.jiedanba.itext5.gm.sign.vo.GetPdfHash;
import cn.jiedanba.itext5.gm.sign.vo.GetPdfHashParamVo;
import cn.jiedanba.itext5.util.PkiUtil;

/**
 * 国密电子签章 分离式签名
 * 
 * @author
 *
 */
public class SignPdf2 {
	private static String cert = "MIIDFTCCArygAwIBAgIPBslAv+CvdtvpAz1PUBxgMAoGCCqBHM9VAYN1MIGIMQswCQYDVQQGEwJDTjESMBAGA1UECAwJR3VhbmdEb25nMREwDwYDVQQHDAhTaGVuWmhlbjE5MDcGA1UECgwwRGlnaXRhbCBDZXJ0aWZpY2F0ZSBBdXRob3JpemF0aW9uIENlbnRlciBDby4gTHRkMRcwFQYDVQQDDA5HbG9iYWwgU3ViIENBMjAeFw0yMzA3MDcwOTEwNTdaFw0yNDA3MDYwOTEwNTdaMGExCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAnlub/kuJznnIExEjAQBgNVBAcMCea3seWcs+W4gjEqMCgGA1UEAwwh5rex5Zyz5biC5rWL6K+V56eR5oqA5pyJ6ZmQ5YWs5Y+4MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEm3bkCoCaQJxm+zo1hvQnnMt8MLy5+CxukQZ1NBZOTS3cfX5la2fYyGXgRQgj1A2O/m6wN4Pz1Y+nQFSYVnRPEaOCAS0wggEpMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFHfjfwKCBeuIUN8/kOEWZ0LG3g+EMB0GA1UdDgQWBBRij3/LGGPBwWaUztDMj13CYrv7ODAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovLzEzOS45Ljg5LjExMjo4MDg1L0dsb2JhbFN1YkNBMi5jcmwwawYIKwYBBQUHAQEEXzBdMCQGCCsGAQUFBzABhhhodHRwOi8vMTM5LjkuODkuMTEyOjgwODIwNQYIKwYBBQUHMAKGKWh0dHA6Ly8xMzkuOS44OS4xMTI6ODA4NS9HbG9iYWxTdWJDQTIuY3J0MAoGCCqBHM9VAYN1A0cAMEQCIGc9hjfu3AAG9O2amxgegmfy2vmw40SyhrpPvcUFrhoGAiBJP5HSOpXsUfMpVKdNopNgLjQZOUry8ondN9jKVhY6rg==";
	private static String privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgBGo3dacOLVg9J1uGZxZ77QFduzZL+R//vve5v79vSS6gCgYIKoEcz1UBgi2hRANCAASbduQKgJpAnGb7OjWG9Cecy3wwvLn4LG6RBnU0Fk5NLdx9fmVrZ9jIZeBFCCPUDY7+brA3g/PVj6dAVJhWdE8R";

	@Test
	public void sign() throws IOException, GeneralSecurityException, DocumentException {
		GetPdfHashParamVo paramVo = new GetPdfHashParamVo();
		Path pdf = Paths.get("src/main/resources", "test.pdf");
		paramVo.setPdf(Files.readAllBytes(pdf));
		paramVo.setPageNo(1);
		paramVo.setLlx(240);
		paramVo.setLly(290);
		paramVo.setUrx(paramVo.getLlx() + 120);
		paramVo.setUry(paramVo.getLly() + 120);
		Path seal = Paths.get("src/main/resources", "深圳测试科技有限公司.seal");
		paramVo.setSeal(SESeal.getInstance(Files.readAllBytes(seal)));
		paramVo.setLocation("深圳");
		paramVo.setReason("国密电子签章测试");

		// 创建签名域，获取pdf文件摘要,组装待签名数据
		GetPdfHash getPdfHash = ITextGM.getPdfHash(paramVo);

		TSAClient tsaClient = new GMTSAClient(new URL("http://43.139.245.54:8082/tsa/sign?type=SM2"), null, null,
				new SM3.Digest());

		PrivateKey prvKey = PkiUtil.getPrivateKey(Base64.decodeBase64(privateKey));

		X509Certificate signCert = PkiUtil.readX509Certificate(Base64.decodeBase64(cert));
		GMTimeStampHook timeStampHook = new GMTimeStampHook(tsaClient);

		// 以下为模拟外部签名测试，电子签章请使用符合国家规范具有国家型号证书的设备进行
		SESV4ContainerV2 signV2 = new SESV4ContainerV2(paramVo.getSeal(), signCert, timeStampHook);

		/**
		 * 模拟签名服务器进行签名，实际使用过程，只需要使用签名服务器对getPdfHash.getTBS_Sign().getEncoded()
		 * 进行一个p1签名即可
		 */
		byte[] p1 = PkiUtil.sign(prvKey, "SM3WithSM2", getPdfHash.getTBS_Sign().getEncoded());

		// 组装电子签章数据
		byte[] p7 = signV2.sign(getPdfHash.getTBS_Sign(), p1);

		// 签署pdf
		byte[] signSuccess = ITextGM.signDeferred(getPdfHash.getEmptySignaturePdf(), p7, getPdfHash.getFieldName());

		FileUtils.writeByteArrayToFile(new File("src/main/resources/signPdf2.pdf"), signSuccess);
	}

}
